

package org.finegold.core.elasticsearch.aspect;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.finegold.core.datascope.handler.ScopeModelHandler;
import org.finegold.core.datascope.model.DataScopeModel;
import org.finegold.core.elasticsearch.annotation.FineEs;
import org.finegold.core.secure.utils.AuthUtil;
import org.finegold.core.tool.utils.Func;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;

/**
 * 操作日志使用spring event异步入库
 *
 * @author QinXueFeng
 */
@Slf4j
@Aspect
@RequiredArgsConstructor
public class FineEsAspect {

	private final ScopeModelHandler scopeModelHandler;

	@Around("@annotation(fineEs)||@within(fineEs)")
	public Object around(ProceedingJoinPoint point, FineEs fineEs) throws Throwable {
		Object[] args = point.getArgs();
		String javaMethodName = getJavaMethodName();
		if("search".equals(point.getSignature().getName())&&args.length==1){
			if(args[0] instanceof QueryBuilder){
				QueryBuilder query = (QueryBuilder) args[0];
				args[0] = getNativeSearchQueryBuilder(query, javaMethodName).build();
			}else if(args[0] instanceof SearchQuery){
				SearchQuery query = (SearchQuery) args[0];
				args[0] = getNativeSearchQueryBuilder(query, javaMethodName).build();
			}
		}else if("search".equals(point.getSignature().getName())&&args.length==2){
			//自行实现

		}

		//执行方法
		Object result = point.proceed(args);
		return result;
	}

	/**
	 * <B>Description:</B> 获取操作类的全限定方法名
	 * @author QinXueFeng
	 * @date 2020/12/7 18:07
	 * @return
	 */
	private String getJavaMethodName() {
		StackTraceElement[] stack = (new Throwable()).getStackTrace();
		for (StackTraceElement ste:stack){
			if(ste.getClassName().contains("org.finegold.")&&!ste.getClassName().contains("FineEsAspect")&&!ste.getMethodName().contains("getJavaMethodName")){
				return ste.getClassName() + "." + ste.getMethodName();
			}
		}
		return null;
	}
	/**
	 * <B>Description:</B> 追加搜索条件
	 * @author QinXueFeng
	 * @date 2020/12/7 18:09
	 * @param var1
	 * @param javaMethodName
	 * @return
	 */
	private NativeSearchQueryBuilder getNativeSearchQueryBuilder(QueryBuilder var1, String javaMethodName) {
		NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder().withQuery(var1);
		//配置条件自己实现
		//DataScopeModel esAuthScopeByMapper = scopeModelHandler.getEsAuthScopeByMapper(javaMethodName, String.valueOf(AuthUtil.getUser().getRoleId()));
		DataScopeModel esAuthScopeByMapper =null;
		if(Func.isNotEmpty(esAuthScopeByMapper)&&Func.isNotEmpty(esAuthScopeByMapper.getScopeType())) {
			if(5!=esAuthScopeByMapper.getScopeType()) {
				BoolQueryBuilder queryBuilder1 = queryBuilder(esAuthScopeByMapper.getScopeType());
				if (Func.isNotEmpty(queryBuilder1)) {
					nativeSearchQueryBuilder.withFilter(queryBuilder1);
				}
			}else if(5==esAuthScopeByMapper.getScopeType()) {
				BoolQueryBuilder queryBuilder2 = customizeQueryBuilder(esAuthScopeByMapper.getScopeValue());
				if (Func.isNotEmpty(queryBuilder2)) {
					nativeSearchQueryBuilder.withFilter(queryBuilder2);
				}
			}
		}
		return nativeSearchQueryBuilder;
	}
	/**
	 * <B>Description:</B> 追加搜索条件
	 * @author QinXueFeng
	 * @date 2020/12/7 18:09
	 * @param var1
	 * @param javaMethodName
	 * @return
	 */
	private NativeSearchQueryBuilder getNativeSearchQueryBuilder(SearchQuery var1, String javaMethodName) {
		BoolQueryBuilder builder = (BoolQueryBuilder)var1.getQuery();
		if(Func.isNotEmpty(AuthUtil.getTenantId())) {
			builder.must(QueryBuilders.termQuery("tenantId", AuthUtil.getTenantId()));
		}
		//配置条件自己实现
		//DataScopeModel esAuthScopeByMapper = scopeModelHandler.getEsAuthScopeByMapper(javaMethodName, String.valueOf(AuthUtil.getUser().getRoleId()));
		DataScopeModel esAuthScopeByMapper =null;
		if(Func.isNotEmpty(esAuthScopeByMapper)&&Func.isNotEmpty(esAuthScopeByMapper.getScopeType())) {
			if(5!=esAuthScopeByMapper.getScopeType()) {
				BoolQueryBuilder queryBuilder1 = queryBuilder(esAuthScopeByMapper.getScopeType());
				if (Func.isNotEmpty(queryBuilder1)) {
					builder.must(queryBuilder1);
				}
			}
		}
		NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder().withQuery(builder)
			.withPageable(var1.getPageable());
		if(Func.isNotEmpty(var1.getElasticsearchSorts())){
			var1.getElasticsearchSorts().forEach(l->{
				nativeSearchQueryBuilder.withSort(l);
			});
		}
		if(Func.isNotEmpty(var1.getAggregations())){
			var1.getAggregations().forEach(l->{
				nativeSearchQueryBuilder.addAggregation(l);
			});
		}
		if(Func.isNotEmpty(var1.getCollapseBuilder())) {
			nativeSearchQueryBuilder.withCollapseField(var1.getCollapseBuilder().getField());
		}
		return nativeSearchQueryBuilder;
	}
	private BoolQueryBuilder queryBuilder(Integer num) {
		BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
		if(Func.isNotEmpty(AuthUtil.getTenantId())) {
			queryBuilder.must(QueryBuilders.termQuery("tenantId", AuthUtil.getTenantId()));
		}
		switch (num){
			case 2:
				queryBuilder.must(QueryBuilders.termQuery("salesmanUserId", AuthUtil.getUserId()));
				break;
			case 3:
				queryBuilder.must(QueryBuilders.termQuery("salesManagerUserId",AuthUtil.getUserId()));
				break;
			case 4:
				queryBuilder.must(QueryBuilders.termQuery("salesManagerUserId",AuthUtil.getUserId()));
				break;
			default:
				break;

		}
		return queryBuilder;
	}
	private BoolQueryBuilder customizeQueryBuilder(String json) {
		BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
		queryBuilder.must(QueryBuilders.wrapperQuery(json));
		return queryBuilder;
	}
}
